/**
******************************************************************************************
* @file observer.c
* @brief Design pattern Observer.
* @date 14 avril 2015
* @author Benjamin Lancinot / Ciro S. Costa
*****************************************************************************************/
/* COPYRIGHT ****************************************************************************
*****************************************************************************************
* Written By Ciro S. Costa /Adapted by Benjamin Lancinot
*
* The MIT License (MIT)
*
* Copyright (c) <2014>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
********************************************************************************************/

#include "observer.h"

/*******************************************************************************************
* PROTOTYPES
********************************************************************************************/

static void _destroy(Observer*);

void _notify(Observer *, int, void *);

/*******************************************************************************************
* FUNCTIONS
********************************************************************************************/

/**
 * @brief Constructor
 * @param impl Pointer to object which are the observer
 * @param notifyImpl Pointer to the function which will be use when a subject need to notify this observer
 * @return The pointer to the new Observer
 **/
Observer* observerNew(void* impl, void (*notifyImpl)(void*, int, void*))
{
	Observer* this = (Observer *) malloc(sizeof(*this));

	this->destroy = _destroy;
	this->notify = _notify;
	this->impl = impl;
	this->notifyImpl = (void (*)(void*, int, void*)) notifyImpl;

	return this;
}

/**
 * @brief Destructor
 * @param This Pointer to the wanted Observer
 **/
static void _destroy(Observer* this){
	if (this != NULL) {
		free(this);
		this = NULL;
	}
}

/**
 * @brief Call the specific notify method
 * @param this Pointer to the specific observer to notify
 * @param type Specific type of subject
 * @param subject Pointer to the specific subject
 **/
 void _notify(Observer *this, int type, void * subject){
	this->notifyImpl(this->impl, type, subject);
}
